



**********************************************
**********************************************
**********************************************
**********************************************
**********************************************
**********************************************

* READ THIS BEFORE PROCEEDING

* run this code on "data.dta"

* analysis was conducted in stata 17. Will probably work if you're in another recent version, but uncomment this line to simulate version 17 if you are using a later version and encounter errors
*version 17

* REQUIRED PACKAGES. Install if not already installed:
*findit spost
*findit grc1leg

* figures use scheme plotplainblind. You can leave this commented this out and just use your own default scheme, but if you use a different scheme, figures will look very different than those in the article
*ssc install blindschemes, replace all
*set scheme plotplainblind 

* for figures to look completely the same, uncomment this line. Note that "graph set" makes a permanent change to your graph font.
*graph set window fontface "Gill Sans MT"

**********************************************
**********************************************
**********************************************
**********************************************
**********************************************
**********************************************




*****************************************
* models in table 1
reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes limit_either, vce( cluster state )
reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_distance lnstatutes limit_either, vce( cluster state )
reg pct_intropassed2 mds1 termlimits chamber_split lnstatutes limit_either, vce( cluster state )
reg pct_intropassed2 mds1 termlimits chamber_distance lnstatutes limit_either, vce( cluster state )
reg pct_intropassed2 lnexpendall termlimits chamber_split lnstatutes limit_either, vce( cluster state )
reg pct_intropassed2 lnexpendall termlimits chamber_distance lnstatutes limit_either, vce( cluster state )


*****************************************
* calculate predicted changes in table 2
* column (a)
quietly reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes limit_either, vce( cluster state )
quietly sum lnstatutes if e(sample), d
local lnstatutes_median = r(p50)
quietly sum salary_real if e(sample), d
local salary_real_median = r(p50)
quietly sum lnexpend if e(sample), d
local lnexpend_median = r(p50)
quietly sum lnsession if e(sample), d
local lnsession_mean = r(mean)
local lnsession_median = r(p50)
local lnsession_sd = r(sd)
quietly sum chamber_split if e(sample), d
local chamber_split_mean = r(mean)
local chamber_split_sd = r(sd)
quietly sum limit_either if e(sample), d
local limit_either_mean = r(mean)
local limit_either_sd = r(sd)
local low : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_mean'-`lnsession_sd') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median'
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_mean'+`lnsession_sd') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median'
local change : di %3.1f `high' - `low'
di "lnsession: Prediction moves from `low' to `high', diff of `change'"
local low : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_median') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median' + _b[chamber_split]*(`chamber_split_mean'-`chamber_split_sd')
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_median') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median' + _b[chamber_split]*(`chamber_split_mean'+`chamber_split_sd')
local change : di %3.1f `high' - `low'
di "chamber_split: Prediction moves from `low' to `high', diff of `change'"
local low : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_median') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median' + _b[limit_either]*(`limit_either_mean'-`limit_either_sd')
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_median') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median' + _b[limit_either]*(`limit_either_mean'+`limit_either_sd')
local change : di %3.1f `high' - `low'
di "limit_either: Prediction moves from `low' to `high', diff of `change'"
* column b
quietly reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_distance lnstatutes limit_either, vce( cluster state )
quietly sum lnstatutes if e(sample), d
local lnstatutes_median = r(p50)
quietly sum salary_real if e(sample), d
local salary_real_median = r(p50)
quietly sum lnexpend if e(sample), d
local lnexpend_median = r(p50)
quietly sum lnsession if e(sample), d
local lnsession_mean = r(mean)
local lnsession_median = r(p50)
local lnsession_sd = r(sd)
quietly sum chamber_distance if e(sample), d
local chamber_distance_median = r(p50)
local chamber_distance_mean = r(mean)
local chamber_distance_sd = r(sd)
quietly sum limit_either if e(sample), d
local limit_either_mean = r(mean)
local limit_either_sd = r(sd)
local low : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_mean'-`lnsession_sd') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median' + _b[chamber_distance]*`chamber_distance_median'
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_mean'+`lnsession_sd') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median' + _b[chamber_distance]*`chamber_distance_median'
local change : di %3.1f `high' - `low'
di "lnsession: Prediction moves from `low' to `high', diff of `change'"
local low :  di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_median') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median' + _b[chamber_distance]*(`chamber_distance_mean' - `chamber_distance_sd')
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_median') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median' + _b[chamber_distance]*(`chamber_distance_mean' + `chamber_distance_sd')
local change : di %3.1f `high' - `low'
di "chamber_distance: Prediction moves from `low' to `high', diff of `change'"
local low : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_median') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median' + _b[chamber_distance]*`chamber_distance_median' + _b[limit_either]*(`limit_either_mean'-`limit_either_sd')
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnsession]*(`lnsession_median') + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median' + _b[chamber_distance]*`chamber_distance_median' + _b[limit_either]*(`limit_either_mean'+`limit_either_sd')
local change : di %3.1f `high' - `low'
di "limit_either: Prediction moves from `low' to `high', diff of `change'"
* column c
quietly reg pct_intropassed2 mds1 termlimits chamber_split lnstatutes limit_either, vce( cluster state )
quietly sum mds1 if e(sample), d
local mds1_mean = r(mean)
local mds1_median = r(p50)
local mds1_sd = r(sd)
quietly sum chamber_split if e(sample), d
local chamber_split_mean = r(mean)
local chamber_split_sd = r(sd)
quietly sum limit_either if e(sample), d
local limit_either_mean = r(mean)
local limit_either_sd = r(sd)
quietly sum lnstatutes if e(sample), d
local lnstatutes_median = r(p50)
local low : di %3.1f _b[_cons] + _b[mds1]*(`mds1_mean'-`mds1_sd') + _b[lnstatutes]*`lnstatutes_median'
local high : di %3.1f _b[_cons] + _b[mds1]*(`mds1_mean'+`mds1_sd') + _b[lnstatutes]*`lnstatutes_median'
local change : di %3.1f `high' - `low'
di "mds1: Prediction moves from `low' to `high', diff of `change'"
local low : di %3.1f _b[_cons] + _b[mds1]*(`mds1_median') + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_split]*(`chamber_split_mean'-`chamber_split_sd')
local high : di %3.1f _b[_cons] + _b[mds1]*(`mds1_median') + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_split]*(`chamber_split_mean'+`chamber_split_sd')
local change : di %3.1f `high' - `low'
di "chamber_split: Prediction moves from `low' to `high', diff of `change'"
local low : di %3.1f _b[_cons] + _b[mds1]*(`mds1_median') + _b[lnstatutes]*`lnstatutes_median' + _b[limit_either]*(`limit_either_mean'-`limit_either_sd')
local high : di %3.1f _b[_cons] + _b[mds1]*(`mds1_median') + _b[lnstatutes]*`lnstatutes_median' + _b[limit_either]*(`limit_either_mean'+`limit_either_sd')
local change : di %3.1f `high' - `low'
di "limit_either: Prediction moves from `low' to `high', diff of `change'"
* column d
quietly reg pct_intropassed2 mds1 termlimits chamber_distance lnstatutes limit_either, vce( cluster state )
quietly sum mds1 if e(sample), d
local mds1_mean = r(mean)
local mds1_median = r(p50)
local mds1_sd = r(sd)
quietly sum chamber_distance if e(sample), d
local chamber_distance_median = r(p50)
local chamber_distance_mean = r(mean)
local chamber_distance_sd = r(sd)
quietly sum limit_either if e(sample), d
local limit_either_mean = r(mean)
local limit_either_sd = r(sd)
quietly sum lnstatutes if e(sample), d
local lnstatutes_median = r(p50)
local low : di %3.1f _b[_cons] + _b[mds1]*(`mds1_mean'-`mds1_sd') + _b[chamber_distance]*`chamber_distance_median' + _b[lnstatutes]*`lnstatutes_median'
local high : di %3.1f _b[_cons] + _b[mds1]*(`mds1_mean'+`mds1_sd') + _b[chamber_distance]*`chamber_distance_median' + _b[lnstatutes]*`lnstatutes_median'
local change : di %3.1f `high' - `low'
di "mds1: Prediction moves from `low' to `high', diff of `change'"
local low : di %3.1f _b[_cons] + _b[mds1]*(`mds1_median') + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_distance]*(`chamber_distance_mean' - `chamber_distance_sd') 
local high : di %3.1f _b[_cons] + _b[mds1]*(`mds1_median') + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_distance]*(`chamber_distance_mean' + `chamber_distance_sd') 
local change : di %3.1f `high' - `low'
di "chamber_distance: Prediction moves from `low' to `high', diff of `change'"
local low : di %3.1f _b[_cons] + _b[mds1]*(`mds1_median') + _b[chamber_distance]*`chamber_distance_median' + _b[lnstatutes]*`lnstatutes_median' + _b[limit_either]*(`limit_either_mean'-`limit_either_sd')
local high : di %3.1f _b[_cons] + _b[mds1]*(`mds1_median') + _b[chamber_distance]*`chamber_distance_median' + _b[lnstatutes]*`lnstatutes_median' + _b[limit_either]*(`limit_either_mean'+`limit_either_sd')
local change : di %3.1f `high' - `low'
di "limit_either: Prediction moves from `low' to `high', diff of `change'"
* column e
quietly reg pct_intropassed2 lnexpendall termlimits chamber_split lnstatutes limit_either, vce( cluster state )
quietly sum lnstatutes if e(sample), d
local lnstatutes_median = r(p50)
quietly sum lnexpendall if e(sample), d
local lnexpendall_mean = r(mean)
local lnexpendall_median = r(p50)
local lnexpendall_sd = r(sd)
quietly sum chamber_split if e(sample), d
local chamber_split_mean = r(mean)
local chamber_split_sd = r(sd)
quietly sum limit_either if e(sample), d
local limit_either_mean = r(mean)
local limit_either_sd = r(sd)
local low : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnexpendall]*(`lnexpendall_mean'-`lnexpendall_sd')
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnexpendall]*(`lnexpendall_mean'+`lnexpendall_sd')
local change : di %3.1f `high' - `low'
di "lnexpendall: Prediction moves from `low' to `high', diff of `change'"
local low : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_split]*(`chamber_split_mean'-`chamber_split_sd') + _b[lnexpendall]*(`lnexpendall_median')
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_split]*(`chamber_split_mean'+`chamber_split_sd') + _b[lnexpendall]*(`lnexpendall_median')
local change : di %3.1f `high' - `low'
di "chamber_split: Prediction moves from `low' to `high', diff of `change'"
local low : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[limit_either]*(`limit_either_mean'-`limit_either_sd') + _b[lnexpendall]*(`lnexpendall_median')
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[limit_either]*(`limit_either_mean'+`limit_either_sd') + _b[lnexpendall]*(`lnexpendall_median')
local change : di %3.1f `high' - `low'
di "limit_either: Prediction moves from `low' to `high', diff of `change'"
* column f
quietly reg pct_intropassed2 lnexpendall termlimits chamber_distance lnstatutes limit_either, vce( cluster state )
quietly sum lnstatutes if e(sample), d
local lnstatutes_median = r(p50)
quietly sum lnexpendall if e(sample), d
local lnexpendall_mean = r(mean)
local lnexpendall_median = r(p50)
local lnexpendall_sd = r(sd)
quietly sum chamber_distance if e(sample), d
local chamber_distance_median = r(p50)
local chamber_distance_mean = r(mean)
local chamber_distance_sd = r(sd)
quietly sum limit_either if e(sample), d
local limit_either_mean = r(mean)
local limit_either_sd = r(sd)
local low : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnexpendall]*(`lnexpendall_mean'-`lnexpendall_sd')+ _b[chamber_distance]*`chamber_distance_median'
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnexpendall]*(`lnexpendall_mean'+`lnexpendall_sd')+ _b[chamber_distance]*`chamber_distance_median'
local change : di %3.1f `high' - `low'
di "lnexpendall: Prediction moves from `low' to `high', diff of `change'"
local low : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnexpendall]*(`lnexpendall_median') + _b[chamber_distance]*(`chamber_distance_mean' - `chamber_distance_sd')
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[lnexpendall]*(`lnexpendall_median') + _b[chamber_distance]*(`chamber_distance_mean' + `chamber_distance_sd')
local change : di %3.1f `high' - `low'
di "chamber_distance: Prediction moves from `low' to `high', diff of `change'"
local low : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[limit_either]*(`limit_either_mean'-`limit_either_sd') + _b[lnexpendall]*(`lnexpendall_median')+ _b[chamber_distance]*`chamber_distance_median'
local high : di %3.1f _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[limit_either]*(`limit_either_mean'+`limit_either_sd') + _b[lnexpendall]*(`lnexpendall_median')+ _b[chamber_distance]*`chamber_distance_median'
local change : di %3.1f `high' - `low'
di "limit_either: Prediction moves from `low' to `high', diff of `change'"




*****************************************
* figure 1
* 1st panel
quietly reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes limit_either, vce( cluster state )
quietly sum lnstatutes if e(sample), d
local lnstatutes_median = r(p50)
local salary_real_median = r(p50)
quietly sum lnexpend if e(sample), d
local lnexpend_median = r(p50)
gen Lses_nosplit = _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_split]*0 + _b[termlimits]*0 + _b[lnsession]*lnsession + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median'
gen Lses_split = _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_split]*1 + _b[termlimits]*0 + _b[lnsession]*lnsession + _b[salary_real]*`salary_real_median' + _b[lnexpend]*`lnexpend_median'
graph twoway ( connect Lses_nosplit t_slength, sort msymbol(none) lcolor(gs3) lpattern(solid) )      ( connect Lses_split t_slength, sort msymbol(none) lcolor(gs3) lpattern(dash) )      ( scatter pct_intropassed2 t_slength, msymbol( none ) mlabel( stateyear ) mlabpos( 0 ) mlabsize( vsmall ) mlabcolor(gs6) ) if e(sample), legend( order( 1 "Partisan congruence" 2 "Partisan incongruence" ) pos(6) cols(2) ) xtitle( "Session days per biennium" ) xscale(log r( 35 600 )) xlabel( 50 100 200 400 ) yscale( r(0 100) ) ylabel(0(20)100) ytitle( "" ) name( "Lses", replace ) nodraw
drop L*
* 2nd panel
quietly reg pct_intropassed2 mds1 termlimits chamber_split lnstatutes limit_either, vce( cluster state )
quietly sum lnstatutes if e(sample), d
local lnstatutes_median = r(p50)
quietly sum mds1 if e(sample), d
local mds1_median = r(p50)
gen Lmds1_nosplit = _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_split]*0 + _b[termlimits]*0 + _b[mds1]*mds1
gen Lmds1_split = _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_split]*1 + _b[termlimits]*0 + _b[mds1]*mds1
graph twoway ( connect Lmds1_nosplit mds1, sort msymbol(none) lcolor(gs3) lpattern(solid) )        ( connect Lmds1_split mds1, sort msymbol(none) lcolor(gs3) lpattern(dash) )        ( scatter pct_intropassed2 mds1, msymbol( none ) mlabel( stateyear ) mlabpos( 0 ) mlabsize( vsmall ) mlabcolor(gs6) ) if e(sample), legend( order( 1 "Partisan congruence" 2 "Partisan incongruence" ) pos(6) cols(2) ) xtitle( "Bowen-Greene 1st dimension" ) yscale( r(0 100) ) ylabel(0(20)100) ytitle( "" ) name( "Lmds1", replace ) nodraw
drop L*
* 3rd panel
quietly reg pct_intropassed2 lnexpendall termlimits chamber_split lnstatutes limit_either, vce( cluster state )
quietly sum lnstatutes if e(sample), d
local lnstatutes_median = r(p50)
gen Lexp_nosplit = _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_split]*0 + _b[termlimits]*0 + _b[lnexpendall]*lnexpendall
gen Lexp_split = _b[_cons] + _b[lnstatutes]*`lnstatutes_median' + _b[chamber_split]*1 + _b[termlimits]*0 + _b[lnexpendall]*lnexpendall
*graph twoway ( connect Lexp lnexpendall, sort msymbol(none) lcolor(gs3) lpattern(solid) ) ( scatter pct_intropassed2 lnexpendall, msymbol( none ) mlabel( stateyear ) mlabpos( 0 ) mlabsize( vsmall ) mlabcolor(gs6) ) if e(sample), legend( off ) xtitle( "Logged expenditures per legislator" ) yscale( r(0 100) ) ylabel(0(20)100) ytitle( "Concurrence rate" ) name( "Lexp", replace )
graph twoway ( connect Lexp_nosplit expendall, sort msymbol(none) lcolor(gs3) lpattern(solid) )      ( connect Lexp_split expendall, sort msymbol(none) lcolor(gs3) lpattern(dash) )      ( scatter pct_intropassed2 expendall, msymbol( none ) mlabel( stateyear ) mlabpos( 0 ) mlabsize( vsmall ) mlabcolor(gs6) ) if e(sample), legend( order( 1 "Partisan congruence" 2 "Partisan incongruence" ) pos(6) cols(2) ) xtitle( "Expenditures per legislator ($1000s)" ) xscale(log r(70 6600)) xlabel( 100 1000 10000 ) yscale( r(0 100) ) ylabel(0(20)100) ytitle( "" ) name( "Lexp", replace ) nodraw
drop L*
* make sure grc1leg package is installed
grc1leg Lses Lmds1 Lexp, col(3) ycommon l1( "Second chamber concurrence rate", size( small ) margin( zero ) )














************************************************
* SUPPLEMENT

* Figure S2
quietly sum t_slength, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity t_slength, normal  legend( order( 1 "Kernel density" 2 "Normal distribution" ) cols(2) ) title( "" ) note( "" ) xtitle( "Biennial session length (days)" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "length_level", replace ) nodraw
quietly sum lnsession, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity lnsession, normal legend( off ) title( "" ) note( "" ) xtitle( "Logged biennial session length" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "length_log", replace ) nodraw
quietly sum salary_real, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity salary_real, normal  legend( off ) title( "" ) note( "" ) xtitle( "Biennial salary ($1000s)" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "salary_level", replace ) nodraw
quietly sum lnsalary, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity lnsalary, normal  legend( off ) title( "" ) note( "" ) xtitle( "Logged biennial salary" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "salary_log", replace ) nodraw
quietly sum expend, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity expend, normal  legend( off ) title( "" ) note( "" ) xtitle( "Biennial non-salary expenditures ($1000s)" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "expend_level", replace ) nodraw
quietly sum lnexpend, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity lnexpend, normal  legend( off ) title( "" ) note( "" ) xtitle( "Logged biennial non-salary expenditures" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "expend_log", replace ) nodraw
grc1leg length_level length_log salary_level salary_log expend_level expend_log, col(2)


* Figure S3
quietly sum totalexp2019, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity totalexp2019, normal  legend( order( 1 "Kernel density" 2 "Normal distribution" ) cols(2) ) title( "" ) note( "" ) xtitle( "Total expenditures ($1000s)" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "total_level", replace ) nodraw
gen lntotalexp = ln(totalexp2019+1)
quietly sum lntotalexp, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity lntotalexp, normal legend( off ) title( "" ) note( "" ) xtitle( "Logged total expenditures" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "total_log", replace ) nodraw
quietly sum expendall, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity expendall, normal  legend( off ) title( "" ) note( "" ) xtitle( "Expenditures per legislator ($1000s)" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "expendall_level", replace ) nodraw
quietly sum lnexpendall, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity lnexpendall, normal  legend( off ) title( "" ) note( "" ) xtitle( "Logged expenditures per legislator" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "expendall_log", replace ) nodraw
quietly sum expendperlog, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity expendperlog, normal  legend( off ) title( "" ) note( "" ) xtitle( "Expenditures per logged legislator ($1000s)" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "expendperlog_level", replace ) nodraw
gen lnexpendperlog = ln( expendperlog+1 )
quietly sum lnexpendperlog, d
local skew : di %3.2f r(skewness)
local kurt : di %3.2f r(kurtosis)
kdensity lnexpendperlog, normal  legend( off ) title( "" ) note( "" ) xtitle( "Logged expenditures per logged legislator" "`skew' skewness, `kurt' kurtosis" ) ytitle( "" ) name( "expendperlog_log", replace ) nodraw
grc1leg total_level total_log expendall_level expendall_log expendperlog_level expendperlog_log, col(2)
drop lntotalexp lnexpendperlog



* Figure S4
quietly reg mds1 expendall, vce( cluster fips )
di sqrt( e(r2) )
local r : di %3.2f sqrt( e(r2) )
local b : di %6.5f _b[expendall]
local s : di %6.5f _se[expendall]
twoway ( lfitci mds1 expendall, estopts( vce( cluster fips ) ) ) ( scatter mds1 expendall, msymbol( none ) mlabel( stateyear ) mlabpos( 0 ) mlabsize( vsmall ) mlabcolor(gs6) ), legend( off ) aspect(1) ytitle( "Bowen-Greene first dimension" ) ylabel(-2(2)10) xtitle( "Expenditures per legislator ($1000s)" ) xscale( r(6500) ) xlabel(0(2000)6000) note( "OLS standard errors clustered by state. b=`b', se=`s', Pearson's r=`r'." , color(gs5) size(vsmall) ) name( "mdsvexpend", replace ) nodraw
* also without CA
quietly reg mds1 expendall if state != "ca", vce( cluster fips )
di sqrt( e(r2) )
local r : di %3.2f sqrt( e(r2) )
local b : di %6.5f _b[expendall]
local s : di %6.5f _se[expendall]
twoway ( lfitci mds1 expendall if state != "ca", estopts( vce( cluster fips ) ) ) ( scatter mds1 expendall if state != "ca", msymbol( none ) mlabel( stateyear ) mlabpos( 0 ) mlabsize( vsmall ) mlabcolor(gs6) ), legend( off ) aspect(1) ytitle( "Bowen-Greene first dimension" ) ylabel(-2(1)5) xtitle( "Expenditures per legislator ($1000s), without CA" ) xscale( r(3100) ) xlabel( 0(1000)3000) note( "OLS standard errors clustered by state. b=`b', se=`s', Pearson's r=`r'." , color(gs5) size(vsmall) ) name( "mdsvexpend_noCA", replace ) nodraw
graph combine mdsvexpend mdsvexpend_noCA



* Table S4
xtset fips year
quietly reg pct_intropassed2 mds1 mds2 termlimits chamber_distance chamber_split lnstatutes limit_either, vce( cluster state )
xtsum mds1 mds2 lnsession salary_real lnexpend if e(sample)
quietly reg pct_intropassed2 lnexpendall termlimits chamber_distance chamber_split lnstatutes limit_either, vce( cluster state )
xtsum pct_intropassed2 lnexpendall termlimits chamber_distance chamber_split lnstatutes limit_either if e(sample)


* Figure S5
graph twoway ( line pct_intropassed2 year ), by( state, note("") iscale(0.55) ) xtitle( "" ) ytitle( "Second chamber concurrence rate" )


* Table S5
reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes limit_either if state!="ca", vce( cluster state )
reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_distance lnstatutes limit_either if state!="ca", vce( cluster state )
reg pct_intropassed2 mds1 termlimits chamber_split lnstatutes limit_either if state!="ca", vce( cluster state )
reg pct_intropassed2 mds1 termlimits chamber_distance lnstatutes limit_either if state!="ca", vce( cluster state )
reg pct_intropassed2 lnexpendall termlimits chamber_split lnstatutes limit_either if state!="ca", vce( cluster state )
reg pct_intropassed2 lnexpendall termlimits chamber_distance lnstatutes limit_either if state!="ca", vce( cluster state )

* Table S6 and S7 preliminaries: Hausman tests. p>0.05 in each case (though it's close in one).
quietly xtreg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes limit_either, fe
estimates store fe
quietly xtreg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes limit_either, re
hausman fe .
quietly xtreg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_distance lnstatutes limit_either, fe
estimates store fe
quietly xtreg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_distance lnstatutes limit_either, re
hausman fe .
quietly xtreg pct_intropassed2 mds1 termlimits chamber_split lnstatutes limit_either, fe
estimates store fe
quietly xtreg pct_intropassed2 mds1 termlimits chamber_split lnstatutes limit_either, re
hausman fe .
quietly xtreg pct_intropassed2 mds1 termlimits chamber_distance lnstatutes limit_either, fe
estimates store fe
quietly xtreg pct_intropassed2 mds1 termlimits chamber_distance lnstatutes limit_either, re
hausman fe .
quietly xtreg pct_intropassed2 lnexpendall termlimits chamber_split lnstatutes limit_either, fe
estimates store fe
quietly xtreg pct_intropassed2 lnexpendall termlimits chamber_split lnstatutes limit_either, re
hausman fe .
quietly xtreg pct_intropassed2 lnexpendall termlimits chamber_distance lnstatutes limit_either, fe
estimates store fe
quietly xtreg pct_intropassed2 lnexpendall termlimits chamber_distance lnstatutes limit_either, re
hausman fe .
* Table S6
xtreg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes limit_either, re vce( cluster fips )
xtreg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_distance lnstatutes limit_either, re vce( cluster fips )
xtreg pct_intropassed2 mds1 termlimits chamber_split lnstatutes limit_either, re vce( cluster fips )
xtreg pct_intropassed2 mds1 termlimits chamber_distance lnstatutes limit_either, re vce( cluster fips )
xtreg pct_intropassed2 lnexpendall termlimits chamber_split lnstatutes limit_either, re vce( cluster fips )
xtreg pct_intropassed2 lnexpendall termlimits chamber_distance lnstatutes limit_either, re vce( cluster fips )
* Table S7
xtreg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes limit_either, mle vce( cluster fips )
xtreg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_distance lnstatutes limit_either, mle vce( cluster fips )
xtreg pct_intropassed2 mds1 termlimits chamber_split lnstatutes limit_either, mle vce( cluster fips )
xtreg pct_intropassed2 mds1 termlimits chamber_distance lnstatutes limit_either, mle vce( cluster fips )
xtreg pct_intropassed2 lnexpendall termlimits chamber_split lnstatutes limit_either, mle vce( cluster fips )
xtreg pct_intropassed2 lnexpendall termlimits chamber_distance lnstatutes limit_either, mle vce( cluster fips )


* Table S8 preliminaries: BIC testing to reduce our models
* ** Test session/salary/staff model with chamber_split
quietly reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes limit_either, vce( cluster state )
quietly fitstat, save
gen i = 1 if e(sample)
* lnsession: BIC and AIC support keeping
quietly reg pct_intropassed2 salary_real lnexpend termlimits chamber_split lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* salary_real: BIC and AIC support dropping
quietly reg pct_intropassed2 lnsession lnexpend termlimits chamber_split lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* lnexpend:  BIC and AIC support dropping
quietly reg pct_intropassed2 lnsession salary_real termlimits chamber_split lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* term limits: BIC and AIC support dropping
quietly reg pct_intropassed2 lnsession salary_real lnexpend chamber_split lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* chamber_split: BIC supports dropping, AIC supports keeping
quietly reg pct_intropassed2 lnsession salary_real lnexpend termlimits lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* lnstatutes: BIC supports dropping, AIC supports keeping
quietly reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_split limit_either if i==1, vce( cluster state )
fitstat, diff
* limit_either: BIC and AIC support keeping
quietly reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes if i==1, vce( cluster state )
fitstat, diff
drop i
* ** Test session/salary/staff model with chamber_distance
quietly reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_distance lnstatutes limit_either, vce( cluster state )
quietly fitstat, save
gen i = 1 if e(sample)
* lnsession: BIC and AIC support keeping
quietly reg pct_intropassed2 salary_real lnexpend termlimits chamber_distance lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* salary_real: BIC and AIC support dropping
quietly reg pct_intropassed2 lnsession lnexpend termlimits chamber_distance lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* lnexpend:  BIC and AIC support dropping
quietly reg pct_intropassed2 lnsession salary_real termlimits chamber_distance lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* term limits: BIC and AIC support dropping
quietly reg pct_intropassed2 lnsession salary_real lnexpend chamber_distance lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* chamber_distance: BIC and AIC support dropping
quietly reg pct_intropassed2 lnsession salary_real lnexpend termlimits lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* lnstatutes: BIC supports dropping, AIC supports keeping
quietly reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_distance limit_either if i==1, vce( cluster state )
fitstat, diff
* limit_either: BIC and AIC support keeping
quietly reg pct_intropassed2 lnsession salary_real lnexpend termlimits chamber_distance lnstatutes if i==1, vce( cluster state )
fitstat, diff
drop i
* ** Test mds1 model with chamber_split
quietly reg pct_intropassed2 mds1 termlimits chamber_split lnstatutes limit_either, vce( cluster state )
quietly fitstat, save
gen i = 1 if e(sample)
* mds1: BIC and AIC support keeping
quietly reg pct_intropassed2 termlimits chamber_split lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* term limits: BIC and AIC support dropping
quietly reg pct_intropassed2 mds1 chamber_split lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* chamber_split: BIC supports dropping, AIC supports keeping
quietly reg pct_intropassed2 mds1 termlimits lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* lnstatutes: BIC supports dropping, AIC supports keeping
quietly reg pct_intropassed2 mds1 termlimits chamber_split limit_either if i==1, vce( cluster state )
fitstat, diff
* limit_either: BIC and AIC support keeping
quietly reg pct_intropassed2 mds1 termlimits chamber_split lnstatutes if i==1, vce( cluster state )
fitstat, diff
drop i
* ** Test mds1 model with chamber_distance
quietly reg pct_intropassed2 mds1 termlimits chamber_distance lnstatutes limit_either, vce( cluster state )
quietly fitstat, save
gen i = 1 if e(sample)
* mds1: BIC and AIC support keeping
quietly reg pct_intropassed2 termlimits chamber_distance lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* term limits: BIC and AIC support dropping
quietly reg pct_intropassed2 mds1 chamber_distance lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* chamber_distance: BIC supports dropping, AIC supports keeping
quietly reg pct_intropassed2 mds1 termlimits lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* lnstatutes: BIC supports dropping, AIC supports keeping
quietly reg pct_intropassed2 mds1 termlimits chamber_distance limit_either if i==1, vce( cluster state )
fitstat, diff
* limit_either: BIC and AIC support keeping
quietly reg pct_intropassed2 mds1 termlimits chamber_distance lnstatutes if i==1, vce( cluster state )
fitstat, diff
drop i
* ** Test expenditure model with chamber_split
quietly reg pct_intropassed2 lnexpendall termlimits chamber_split lnstatutes limit_either, vce( cluster state )
quietly fitstat, save
gen i = 1 if e(sample)
* lnexpendall: BIC and AIC support keeping
quietly reg pct_intropassed2 termlimits chamber_split lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* termlimits: BIC and AIC support dropping
quietly reg pct_intropassed2 lnexpendall chamber_split lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* chamber_split: BIC support dropping, AIC supports keeping
quietly reg pct_intropassed2 lnexpendall termlimits lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* lnstatutes: BIC and AIC support dropping
quietly reg pct_intropassed2 lnexpendall termlimits chamber_split limit_either if i==1, vce( cluster state )
fitstat, diff
* limit_either: BIC and AIC support keeping
quietly reg pct_intropassed2 lnexpendall termlimits chamber_split lnstatutes if i==1, vce( cluster state )
fitstat, diff
drop i
* ** Test expenditure model with chamber_distance
quietly reg pct_intropassed2 lnexpendall termlimits chamber_distance lnstatutes limit_either, vce( cluster state )
quietly fitstat, save
gen i = 1 if e(sample)
* lnexpendall: BIC and AIC support keeping
quietly reg pct_intropassed2 termlimits chamber_distance lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* termlimits: BIC and AIC support dropping
quietly reg pct_intropassed2 lnexpendall chamber_distance lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* chamber_distance: BIC supports dropping, AIC supports keeping
quietly reg pct_intropassed2 lnexpendall termlimits lnstatutes limit_either if i==1, vce( cluster state )
fitstat, diff
* lnstatutes: BIC and AIC support dropping
quietly reg pct_intropassed2 lnexpendall termlimits chamber_distance limit_either if i==1, vce( cluster state )
fitstat, diff
* limit_either: BIC and AIC support keeping
quietly reg pct_intropassed2 lnexpendall termlimits chamber_distance lnstatutes if i==1, vce( cluster state )
fitstat, diff
drop i
**** bic reduced models, for the record. We have only 6 models instead of 3, since models (a) and (b) reduced to the same model, models (c) and (d) reduced to the same model, and models (e) and (f) reduced to the same model.
reg pct_intropassed2 lnsession limit_either, vce( cluster state )
reg pct_intropassed2 mds1 limit_either, vce( cluster state )
reg pct_intropassed2 lnexpendall limit_either, vce( cluster state )
* Table S8, run on the same observations as in models in the main manuscript
quietly reg pct_intropassed2 lnexpendall termlimits chamber_distance lnstatutes limit_either, vce( cluster state )
gen t_sample = 1 if e(sample)
reg pct_intropassed2 lnsession limit_either if t_sample == 1, vce( cluster state )
reg pct_intropassed2 lnsession limit_either makse joint if t_sample == 1, vce( cluster state )
reg pct_intropassed2 mds1 limit_either if t_sample == 1, vce( cluster state )
reg pct_intropassed2 mds1 limit_either makse joint if t_sample == 1, vce( cluster state )
reg pct_intropassed2 lnexpendall limit_either if t_sample == 1, vce( cluster state )
reg pct_intropassed2 lnexpendall limit_either makse joint if t_sample == 1, vce( cluster state )
drop t_sample




* Table S9
reg pct_hb_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes limit_either, vce( cluster state )
reg pct_sb_intropassed2 lnsession salary_real lnexpend termlimits chamber_split lnstatutes limit_either, vce( cluster state )
reg pct_hb_intropassed2 mds1 termlimits chamber_split lnstatutes limit_either, vce( cluster state )
reg pct_sb_intropassed2 mds1 termlimits chamber_split lnstatutes limit_either, vce( cluster state )
reg pct_hb_intropassed2 lnexpendall termlimits chamber_split lnstatutes limit_either, vce( cluster state )
reg pct_sb_intropassed2 lnexpendall termlimits chamber_split lnstatutes limit_either, vce( cluster state )
